﻿#ifndef ENCODING_H
#define ENCODING_H
/***********************************************************************
 *  COPYRIGHT NOTICE
 *	Copyright(c) 2017-2018,塔米智能科技（北京）有限公司
 *	All rights reserved.
 *	@file       encoding.h
 *	@version	1.0
 *	@author		张利利
 *	@date		2017年09月06日
 *
 ***********************************************************************/

/***********************************************************************
 * 编译器：minGw、MSVC、clong。linux下utf8编码是无BOM头的，windows下utf8下是带有BOM头的。（windows下设置加BOM、用c++11优化的加u8）
 * QT、C++中编码问题
 *      源码字符集：源码文件是使用何种编码保存的
 *      执行字符集：程序执行时内存中字符串编码
 * 0.C++98：未规定源码字符集，未规定执行字符集
 * 要跨平台，这两个字符集必须都是"确定"的.如果都为utf-8，那就天下太平了.
 * 源码保存成utf-8没什么困难，但执行字符集需要时utf-8，就有些困难：
 * 1.对GCC来说，这个问题很简单（默认的编码选项）
 *      GCC下两个都可以根据自己的喜好编码（如不指定，默认都是utf-8）
 *      编码文件保存成utf8即可（带或不带BOM均可）早期gcc不支持带BOM的utf8源码文件，GCC4.6以后就支持了。
 * 2.对MSCV来说，这个问题异常复杂：
 *      源码字符集：有BOM则按BOM解释，无则使用本地Locale字符集（随系统设置而变）
 *      执行字符集：使用本地locale字符集（随系统设置而变）
 *      宽执行字符集：...
 *   直到MSVC2010sp1：源码保存成带BOM的utf8，utf16，然后添加
 *      #if _MSC_VER >= 1600
 *      #pragma execution_character_set("utf-8")
 *      #endif
 * 3.要想跨GCC4.6+和MSVC2010sp1+，我们需要取它们的交集：
 *      源码保存成带BOM的utf8
 *      为MSVC添加#pragma
 *
 * C++11：MSVC支持C++11的String Literal后，就可以不用pragma。直接：char str[] = u8"程序员狗蛋";
 * C++11为“执行字符集”所做的努力，规定了utf8、utf16和utf32这三种的执行字符集:
 *      char* 	  : u8"中文"
 *      char16_t* : u"中文"
 *      char32_t* ：U"中文"
 * 可是C++11并没有规定源码字符集。C++标准对编译器：不管这个文件具体编码是什么，但必须生成对应utf8编码的字节流，对此：
 * MSVC：源码文件必须有BOM，不然就认为是本地locale编码
 * GCC：默认是utf8编码，除非通过命令行通知是其他编码
 * 在C++11标准下，对源码编码简单的处理办法：使用带BOM的UTF8保存。
 *
 ***************************************************
 ***************************************************
 ***************************************************
 ***************************************************
 * gb18030字符集兼容了gbk字符集，以两个字节表示一个文字。windows系统可能使用的就是这两种的一种。
 * unicode字符集以2个或以上的字节表示一个汉字。
 * 通用字符集（Universal Character Set, UCS）是由ISO制定的ISO 10646（或称ISO/IEC 10646）标准所定义的标准字符集。UCS-2用两个字节编码，UCS-4用4个字节编码。
 * utf8字符集以2个或以上的字节表示一个汉字。实际上具体的数值和unicode有很大的相关性。
 * ISO-8859-1编码是单字节编码，向下兼容ASCII，其编码范围是0x00-0xFF。亦称为Latin1。
 *
 * QString内部可能是使用unicode字符集来存储文字。具体输出的时候，就可以输出该文字对应的unicode, ucs4, utf8, gb18030的编码。
 * 使用qtcreator创建main.cpp，它默认代码里的汉字使用utf8字符集。不要使用msvc编译器，因为它默认汉字使用gb18030字符集
 *
 * #include <QCoreApplication>
 * #include <QDebug>
 * int main(int argc, char *argv[])
 * {
 *     QCoreApplication a(argc, argv);
 *     QString tmp="汉字";
 *     qDebug() << "tmp=" << tmp << endl;
 *     qDebug() << "toUtf8" << tmp.toUtf8() << endl;       //返回utf8编码的一串数字
 *     qDebug() << "toLatin1" << tmp.toLatin1() << endl;   //"汉字"不在latin1字符集中，所以结果无意义
 *     char *p = new char[1+strlen(tmp.toLatin1().data())];
 *     strcpy(p, tmp.toLatin1().data());
 *     for (int i=0; p[i] != '\0'; i++)
 *     {
 *         printf("0x%02x ", p[i]);
 *     }
 *     printf("\n");
 *     delete p;
 *     qDebug() << "toLocal8bit" << tmp.toLocal8Bit() << endl;//返回windows操作系统设置的字符集gb18030的编码
 *     qDebug() << "toUcs4" << tmp.toUcs4() << endl;           //返回ucs4编码组成的QVector，一个汉字占用4字节
 *     return a.exec();
 *  }
 ***********************************************************************/

#endif // ENCODING_H
